package com.baidu.mpks.permission.service;

import com.baidu.mpks.user.dao.UserDao;
import com.baidu.mpks.user.service.UserService;
import com.baidu.mpks.usergroup.domain.UserGroup;
import com.baidu.mpks.usergroup.dto.Resources;
import com.baidu.mpks.usergroup.enums.UserGroupType;
import com.baidu.mpks.usergroup.service.UserGroupService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class PermissionHelper {

    @Autowired
    @Lazy
    private UserDao userDao;
    @Autowired
    @Lazy
    private UserService userService;
    @Autowired
    @Lazy
    private PermissionCacheService permissionCacheService;
    @Autowired
    @Lazy
    private PermissionManageService permissionManageService;
    @Autowired
    @Lazy
    private UserGroupService userGroupService;

    public PermissionHelper() {
    }

    public Map<PermissionService.OP, Info> getPermissionCachedByUserId(String userId) throws IOException {
        Map<String, Map<String, Object>> permissionData = this.getPermissionDataCached(userId);
        Map<PermissionService.OP, PermissionHelper.Info> result = new EnumMap(PermissionService.OP.class);
        PermissionService.OP[] var4 = PermissionService.OP.values();
        int var5 = var4.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            PermissionService.OP op = var4[var6];
            result.put(op, new PermissionHelper.Info((Map)permissionData.get(op.getName())));
        }

        return result;
    }

    public PermissionHelper.Info getPermissionCachedByUserIdWithOp(String userId, PermissionService.OP op) throws IOException {
        Map<String, Map<String, Object>> permissionData = this.getPermissionDataCached(userId);
        return new PermissionHelper.Info((Map)permissionData.get(op.getName()));
    }

    private Map<String, Map<String, Object>> getPermissionDataCached(String userId) throws IOException {
        Map<String, Map<String, Object>> permissionData = this.permissionCacheService.getUserPermission(userId);
        if (permissionData == null) {
            List<Integer> roleIds = (List)this.userService.getUserAllRoles(userId).stream().map(Resources::getId).collect(Collectors.toList());
            permissionData = this.permissionManageService.getAllDataPermissionByUserIdAndRoleIdClassForNew(roleIds, userId);
            this.permissionCacheService.addUserPermission(userId, permissionData);
        }

        return permissionData;
    }

    public Map<String, Object> getPermissionDataCachedV3(String userId) throws IOException {
        Map<String, Object> permissionData = this.permissionCacheService.getUserPermissionV3(userId);
        if (permissionData == null) {
            List<Integer> roleIds = (List)this.userService.getUserAllRoles(userId).stream().map(Resources::getId).collect(Collectors.toList());
            permissionData = this.permissionManageService.getAllDataPermissionByUserIdAndRoleIdClassV3(roleIds, userId);
            this.permissionCacheService.addUserPermissionV3(userId, permissionData);
        }

        return permissionData;
    }

    private void addGroupRoleIdsByUserId(String userId, List<Integer> roleIds) {
        List<UserGroup> userGroups = this.userGroupService.getUserGroupsByUserId(userId, UserGroupType.DEPARTMENT.getName());
        if (CollectionUtils.isNotEmpty(userGroups)) {
            List<Resources> groupRoles = this.userGroupService.getRolesByGroup(((UserGroup)userGroups.get(0)).getId());
            if (CollectionUtils.isNotEmpty(groupRoles)) {
                groupRoles.forEach((role) -> {
                    roleIds.add(role.getId());
                });
            }
        }

    }

    public Map<String, Object> getPermissiondataByOp(Map<String, Object> permissionData, List<String> ops) {
        Map<String, Object> result = new HashMap();
        Map<String, Map<String, Set<String>>> fieldAuthInfo = new HashMap();
        Map<String, Set<String>> recordAuthInfo = this.filterPermissiondataByOp((Map)permissionData.get("recordAuthInfo"), ops);
        Map<String, Set<String>> sourceAuthInfo = this.filterPermissiondataByOp((Map)permissionData.get("sourceAuthInfo"), ops);
        Map<String, Map<String, Set<String>>> field = (Map)permissionData.get("fieldAuthInfo");
        Iterator var8 = field.keySet().iterator();

        while(var8.hasNext()) {
            String classId = (String)var8.next();
            Map<String, Set<String>> props = (Map)field.get(classId);
            Map<String, Set<String>> propsWithOP = this.filterPermissiondataByOp(props, ops);
            if (MapUtils.isNotEmpty(propsWithOP)) {
                fieldAuthInfo.put(classId, propsWithOP);
            }
        }

        result.put("superAdmin", permissionData.get("superAdmin"));
        result.put("sourceAuthInfo", sourceAuthInfo);
        result.put("recordAuthInfo", recordAuthInfo);
        result.put("fieldAuthInfo", fieldAuthInfo);
        return result;
    }

    public Map<String, Set<String>> filterPermissiondataByOp(Map<String, Set<String>> permissiondata, List<String> ops) {
        Map<String, Set<String>> result = new HashMap();
        Iterator var4 = ops.iterator();

        while(var4.hasNext()) {
            String op = (String)var4.next();
            Iterator var6 = permissiondata.entrySet().iterator();

            while(var6.hasNext()) {
                Map.Entry<String, Set<String>> entry = (Map.Entry)var6.next();
                if (((Set)entry.getValue()).contains(op)) {
                    Set<String> value = new HashSet();
                    if (result.get(entry.getKey()) != null) {
                        value = (Set)result.get(entry.getKey());
                    }

                    ((Set)value).add(op);
                    result.put(entry.getKey(), value);
                }
            }
        }

        return result;
    }

    public static class Info {
        @NonNull
        private Set<String> recordAuthInfo;
        @NonNull
        private Set<String> sourceAuthInfo;
        @NonNull
        private Map<String, Set<String>> fieldAuthInfo;

        private Info(Map<String, Object> map) {
            this.recordAuthInfo = (Set)map.getOrDefault("recordAuthInfo", Collections.emptySet());
            this.sourceAuthInfo = (Set)map.getOrDefault("sourceAuthInfo", Collections.emptySet());
            this.fieldAuthInfo = (Map)map.getOrDefault("fieldAuthInfo", Collections.emptyMap());
        }

        @NonNull
        public Set<String> getRecordAuthInfo() {
            return this.recordAuthInfo;
        }

        @NonNull
        public Set<String> getSourceAuthInfo() {
            return this.sourceAuthInfo;
        }

        @NonNull
        public Map<String, Set<String>> getFieldAuthInfo() {
            return this.fieldAuthInfo;
        }
    }
}
